gsk_cairo_node_new
gsk_cairo_node_get_draw_context
gsk_container_node_new
-gsk_container_node_append_child
gsk_container_node_get_n_children
gsk_container_node_get_child
gsk_transform_node_new
GskRenderer *renderer);
GDK_AVAILABLE_IN_3_90
-GskRenderNode * gsk_container_node_new (void);
+GskRenderNode * gsk_container_node_new (GskRenderNode **children,
+ guint n_children);
GDK_AVAILABLE_IN_3_90
-GskRenderNode * gsk_container_node_append_child (GskRenderNode *node,
- GskRenderNode *child);
+guint gsk_container_node_get_n_children (GskRenderNode *node);
GDK_AVAILABLE_IN_3_90
-guint gsk_container_node_get_n_children (GskRenderNode *node);
-GDK_AVAILABLE_IN_3_90
-GskRenderNode * gsk_container_node_get_child (GskRenderNode *node,
- guint idx);
+GskRenderNode * gsk_container_node_get_child (GskRenderNode *node,
+ guint idx);
GDK_AVAILABLE_IN_3_90
GskRenderNode * gsk_transform_node_new (GskRenderNode *child,
{
GskRenderNode render_node;
- GPtrArray *children;
+ GskRenderNode **children;
+ guint n_children;
};
static void
gsk_container_node_finalize (GskRenderNode *node)
{
GskContainerNode *container = (GskContainerNode *) node;
+ guint i;
+
+ for (i = 0; i < container->n_children; i++)
+ gsk_render_node_unref (container->children[i]);
- g_ptr_array_unref (container->children);
+ g_free (container->children);
}
static void
GskContainerNode *container = (GskContainerNode *) node;
guint i;
- for (i = 1; i < container->children->len; i++)
+ for (i = 1; i < container->n_children; i++)
{
- gsk_render_node_make_immutable (g_ptr_array_index (container->children, i));
+ gsk_render_node_make_immutable (container->children[i]);
}
}
/**
* gsk_container_node_new:
+ * @children: (array length=n_children) (transfer none): The children of the node
+ * @n_children: Number of children in the @children array
*
- * Creates a new #GskRenderNode instance for holding multiple different
- * render nodes. You can use gsk_container_node_append_child() to add
- * nodes to the container.
+ * Creates a new #GskRenderNode instance for holding the given @children.
+ * The new node will acquire a reference to each of the children.
*
* Returns: (transfer full): the new #GskRenderNode
*
* Since: 3.90
*/
GskRenderNode *
-gsk_container_node_new (void)
+gsk_container_node_new (GskRenderNode **children,
+ guint n_children)
{
GskContainerNode *container;
+ guint i;
container = (GskContainerNode *) gsk_render_node_new (&GSK_CONTAINER_NODE_CLASS);
- container->children = g_ptr_array_new_with_free_func ((GDestroyNotify) gsk_render_node_unref);
+ container->children = g_memdup (children, sizeof (GskRenderNode *) * n_children);
+ container->n_children = n_children;
- return &container->render_node;
-}
+ for (i = 0; i < container->n_children; i++)
+ gsk_render_node_ref (container->children[i]);
-/**
- * gsk_container_node_append_child:
- * @node: a container node
- * @child: a #GskRenderNode
- *
- * Appends @child to the list of children of @node.
- *
- * This function acquires a reference on @child.
- *
- * Returns: (transfer none): the #GskRenderNode
- *
- * Since: 3.90
- */
-GskRenderNode *
-gsk_container_node_append_child (GskRenderNode *node,
- GskRenderNode *child)
-{
- GskContainerNode *container = (GskContainerNode *) node;
-
- g_return_val_if_fail (GSK_IS_RENDER_NODE_TYPE (node, GSK_CONTAINER_NODE), NULL);
- g_return_val_if_fail (GSK_IS_RENDER_NODE (child), node);
- g_return_val_if_fail (node->is_mutable, node);
-
- g_ptr_array_add (container->children, gsk_render_node_ref (child));
-
- return node;
+ return &container->render_node;
}
/**
g_return_val_if_fail (GSK_IS_RENDER_NODE_TYPE (node, GSK_CONTAINER_NODE), 0);
- return container->children->len;
+ return container->n_children;
}
GskRenderNode *
GskContainerNode *container = (GskContainerNode *) node;
g_return_val_if_fail (GSK_IS_RENDER_NODE_TYPE (node, GSK_CONTAINER_NODE), NULL);
- g_return_val_if_fail (idx < container->children->len, 0);
+ g_return_val_if_fail (idx < container->n_children, 0);
- return g_ptr_array_index (container->children, idx);
+ return container->children[idx];
}
/*** GSK_TRANSFORM_NODE ***/
else
{
graphene_matrix_t m1, m2, m3;
- GskRenderNode *transform_node, *container_node;
+ GskRenderNode *transform_node, *icon_node;
double offset_x, offset_y;
gtk_snapshot_get_offset (snapshot, &offset_x, &offset_y);
graphene_matrix_init_translate (&m2, &GRAPHENE_POINT3D_INIT(- width / 2.0, - height / 2.0, 0));
graphene_matrix_multiply (&m2, &m3, &m1);
- container_node = gsk_container_node_new ();
- gsk_render_node_set_name (container_node, "CSS Icon Transform Container");
- transform_node = gsk_transform_node_new (container_node, &m1);
+ gtk_snapshot_push (snapshot, FALSE, "CSS Icon Transform Container");
+ gtk_css_image_builtin_snapshot (image, snapshot, width, height, builtin_type);
+ icon_node = gtk_snapshot_pop (snapshot);
+
+ transform_node = gsk_transform_node_new (icon_node, &m1);
gsk_render_node_set_name (transform_node, "CSS Icon Transform");
gtk_snapshot_append_node (snapshot, transform_node);
- gtk_snapshot_push_node (snapshot, container_node);
- gtk_css_image_builtin_snapshot (image, snapshot, width, height, builtin_type);
- gtk_snapshot_pop (snapshot);
+ gsk_render_node_unref (transform_node);
+ gsk_render_node_unref (icon_node);
}
}
static GtkSnapshotState *
gtk_snapshot_state_new (GtkSnapshotState *parent,
+ char *name,
cairo_region_t *clip,
- GskRenderNode *node)
+ double translate_x,
+ double translate_y)
{
GtkSnapshotState *state;
state = g_slice_new0 (GtkSnapshotState);
- state->node = node;
+ state->nodes = g_ptr_array_new_with_free_func ((GDestroyNotify) gsk_render_node_unref);
+
state->parent = parent;
+ state->name = name;
+ state->translate_x = translate_x;
+ state->translate_y = translate_y;
if (clip)
state->clip_region = cairo_region_reference (clip);
static void
gtk_snapshot_state_free (GtkSnapshotState *state)
{
+ g_ptr_array_unref (state->nodes);
+
if (state->clip_region)
cairo_region_destroy (state->clip_region);
+ g_free (state->name);
+
g_slice_free (GtkSnapshotState, state);
}
const char *name,
...)
{
- cairo_rectangle_int_t extents;
-
- cairo_region_get_extents (clip, &extents);
+ char *str;
snapshot->state = NULL;
snapshot->renderer = renderer;
- snapshot->root = gsk_container_node_new ();
if (name)
{
va_list args;
- char *str;
va_start (args, name);
str = g_strdup_vprintf (name, args);
va_end (args);
-
- gsk_render_node_set_name (snapshot->root, str);
-
- g_free (str);
}
+ else
+ str = NULL;
- snapshot->state = gtk_snapshot_state_new (NULL, (cairo_region_t *) clip, snapshot->root);
+ snapshot->state = gtk_snapshot_state_new (NULL,
+ str,
+ (cairo_region_t *) clip,
+ 0, 0);
}
GskRenderNode *
gtk_snapshot_finish (GtkSnapshot *snapshot)
{
- gtk_snapshot_pop (snapshot);
+ GskRenderNode *result;
+
+ result = gtk_snapshot_pop (snapshot);
if (snapshot->state != NULL)
{
g_warning ("Too many gtk_snapshot_push() calls.");
}
- return snapshot->root;
-}
-
-/**
- * gtk_snapshot_push_node:
- * @snapshot: a #GtkSnapshot
- * @node: the render node to push
- *
- * Makes @node the new current render node. You are responsible for adding
- * @node to the snapshot.
- *
- * Since: 3.90
- */
-void
-gtk_snapshot_push_node (GtkSnapshot *snapshot,
- GskRenderNode *node)
-{
- g_return_if_fail (gsk_render_node_get_node_type (node) == GSK_CONTAINER_NODE);
-
- snapshot->state = gtk_snapshot_state_new (snapshot->state, snapshot->state->clip_region, node);
+ return result;
}
/**
* gtk_snapshot_push:
* @snapshot: a #GtkSnapshot
+ * @keep_coordinates: If %TRUE, the current offset and clip will be kept.
+ * Otherwise, the clip will be unset and the offset will be reset to
+ * (0, 0).
* @bounds: the bounds for the new node
* @name: (transfer none): a printf() style format string for the name for the new node
* @...: arguments to insert into the format string
*/
void
gtk_snapshot_push (GtkSnapshot *snapshot,
+ gboolean keep_coordinates,
const char *name,
...)
{
- GskRenderNode *node;
-
- node = gsk_container_node_new ();
+ char *str;
if (name)
{
va_list args;
- char *str;
va_start (args, name);
str = g_strdup_vprintf (name, args);
va_end (args);
-
- gsk_render_node_set_name (node, str);
-
- g_free (str);
}
+ else
+ str = NULL;
- gtk_snapshot_append_node (snapshot, node);
- gtk_snapshot_push_node (snapshot, node);
- gsk_render_node_unref (node);
+ if (keep_coordinates)
+ {
+ snapshot->state = gtk_snapshot_state_new (snapshot->state,
+ str,
+ snapshot->state->clip_region,
+ snapshot->state->translate_x,
+ snapshot->state->translate_y);
+ }
+ else
+ {
+ snapshot->state = gtk_snapshot_state_new (snapshot->state,
+ str,
+ NULL,
+ 0, 0);
+ }
}
/**
* Removes the top element from the stack of render nodes,
* making the node underneath the current node again.
*
+ * Returns: (transfer full) (allow none): A #GskRenderNode for
+ * the contents that were rendered to @snapshot since
+ * the corresponding gtk_snapshot_push() call
+ *
* Since: 3.90
*/
-void
+GskRenderNode *
gtk_snapshot_pop (GtkSnapshot *snapshot)
{
GtkSnapshotState *state;
+ GskRenderNode *node;
if (snapshot->state == NULL)
{
g_warning ("Too many gtk_snapshot_pop() calls.");
- return;
+ return NULL;
}
state = snapshot->state;
snapshot->state = state->parent;
+ if (state->nodes->len == 0)
+ {
+ node = NULL;
+ }
+ else if (state->nodes->len == 1)
+ {
+ node = gsk_render_node_ref (g_ptr_array_index (state->nodes, 0));
+ }
+ else
+ {
+ node = gsk_container_node_new ((GskRenderNode **) state->nodes->pdata,
+ state->nodes->len);
+ gsk_render_node_set_name (node, state->name);
+ }
+
gtk_snapshot_state_free (state);
+
+ return node;
}
/**
if (snapshot->state)
{
- gsk_container_node_append_child (snapshot->state->node, node);
+ g_ptr_array_add (snapshot->state->nodes, gsk_render_node_ref (node));
}
else
{
GDK_AVAILABLE_IN_3_90
void gtk_snapshot_push (GtkSnapshot *snapshot,
+ gboolean keep_coordinates,
const char *name,
- ...) G_GNUC_PRINTF(2, 3);
+ ...) G_GNUC_PRINTF (3, 4);
GDK_AVAILABLE_IN_3_90
-void gtk_snapshot_push_node (GtkSnapshot *snapshot,
- GskRenderNode *node);
-GDK_AVAILABLE_IN_3_90
-void gtk_snapshot_pop (GtkSnapshot *snapshot);
+GskRenderNode * gtk_snapshot_pop (GtkSnapshot *snapshot) G_GNUC_WARN_UNUSED_RESULT;
GDK_AVAILABLE_IN_3_90
void gtk_snapshot_translate_2d (GtkSnapshot *snapshot,
struct _GtkSnapshotState {
GtkSnapshotState *parent;
- GskRenderNode *node;
+ char *name;
+ GPtrArray *nodes;
cairo_region_t *clip_region;
double translate_x;
struct _GtkSnapshot {
GtkSnapshotState *state;
- GskRenderNode *root;
GskRenderer *renderer;
};